import config from '@/config'
import { getToken, removeToken, setToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { toast, showConfirm, tansParams } from '@/utils/common'

let timeout = 10000
const baseUrl = config.baseUrl

// 是否正在刷新token
let isRefreshing = false
// 重试队列
let retryRequests = []

const request = config => {
  // 是否需要设置 token
  const isToken = (config.headers || {}).isToken === false
  config.headers = config.headers || {}
  // 设置默认的 Content-Type
  config.headers['Content-Type'] = 'application/json'
  if (getToken() && !isToken) {
    config.headers['Authorization'] = 'Bearer ' + getToken()
  }
  // get请求映射params参数
  if (config.params) {
    let url = config.url + '?' + tansParams(config.params)
    url = url.slice(0, -1)
    config.url = url
  }
  
  console.log('请求配置:', {
    url: config.baseUrl || baseUrl + config.url,
    method: config.method || 'get',
    headers: config.headers,
    data: config.data
  })
  
  return new Promise((resolve, reject) => {
    uni.request({
        method: config.method || 'get',
        timeout: config.timeout ||  timeout,
        url: config.baseUrl || baseUrl + config.url,
        data: config.data,
        header: config.headers,
        dataType: 'json'
      }).then(response => {
        console.log('原始响应对象:', response);
        console.log('响应数据:', response)
        let statusCode = response.statusCode
        let errMsg = response.errMsg
        let res = response
        
        const code = statusCode || 200
        const msg = errorCode[code] || errMsg || errorCode['default']
        
        // 处理 HTTP 状态码 401
        if (code === 401) {
          console.log('request.js: HTTP状态码401被捕获')
          // 如果当前请求是 /refresh 接口，且它返回 401，则直接跳转登录
          if (config.url.includes('/refresh')) {
            console.log('request.js: 刷新token请求HTTP状态码401，直接跳转登录')
            removeToken()
            showConfirm('登录状态已过期，请重新登录', () => {
              uni.reLaunch({
                url: '/pages/login/login'
              })
            })
            return reject('401') // 阻止 Promise 继续执行
          }

          if (!isRefreshing) {
            isRefreshing = true
            // 尝试刷新token
            console.log('request.js: 尝试刷新token (HTTP 401)')
            return request({
              url: '/refresh',
              method: 'post',
              headers: {
                isToken: false
              }
            }).then(res => {
              if (res.code === 200 && res.data && res.data.token) {
                console.log('request.js: token刷新成功')
                setToken(res.data.token)
                // 重试队列中的请求
                retryRequests.forEach(cb => cb(res.data.token))
                retryRequests = []
                // 重试当前请求
                config.headers['Authorization'] = 'Bearer ' + res.data.token
                return uni.request(config)
              } else {
                // 刷新token失败，清除token并跳转到登录页
                console.log('request.js: token刷新失败，准备跳转登录 (HTTP 401)')
                removeToken()
                showConfirm('登录状态已过期，请重新登录', () => {
                  uni.reLaunch({
                    url: '/pages/login/login'
                  })
                })
                reject('401')
              }
            }).catch(error => {
              console.error('刷新token失败:', error)
              console.log('request.js: 刷新token异常，准备跳转登录 (HTTP 401)')
              removeToken()
              showConfirm('登录状态已过期，请重新登录', () => {
                uni.reLaunch({
                  url: '/pages/login/login'
                })
              })
              reject('401')
            }).finally(() => {
              isRefreshing = false
            })
          } else {
            // 将请求加入重试队列
            console.log('request.js: 将请求加入重试队列 (HTTP 401)')
            return new Promise(resolve => {
              retryRequests.push(token => {
                config.headers['Authorization'] = 'Bearer ' + token
                resolve(uni.request(config))
              })
            })
          }
        }
        
        if (code === 500) {
          console.error('服务器错误:', msg)
          toast(msg)
          reject('500')
        } else if (code !== 200) {
          console.error('请求错误:', msg)
          toast(msg)
          reject(code)
        }
        
        if (!res.data) {
          console.error('响应数据为空')
          return reject(new Error('响应数据为空'))
        }
        
        // 处理业务状态码 401 (当 HTTP 状态码为 200 时)
        if (res.data.code === 401) {
          console.log('request.js: 业务状态码401被捕获')
          // 如果当前请求是 /refresh 接口，且它返回 401，则直接跳转登录
          if (config.url.includes('/refresh')) {
            console.log('request.js: 刷新token请求业务状态码401，直接跳转登录')
            removeToken()
            showConfirm('登录状态已过期，请重新登录', () => {
              uni.reLaunch({
                url: '/pages/login/login'
              })
            })
            return reject('401') // 阻止 Promise 继续执行
          }

          if (!isRefreshing) {
            isRefreshing = true
            // 尝试刷新token
            console.log('request.js: 业务状态码401，尝试刷新token')
            return request({
              url: '/refresh',
              method: 'post',
              headers: {
                isToken: false
              }
            }).then(res => {
              if (res.code === 200 && res.data && res.data.token) {
                console.log('request.js: 业务状态码401，token刷新成功')
                setToken(res.data.token)
                // 重试队列中的请求
                retryRequests.forEach(cb => cb(res.data.token))
                retryRequests = []
                // 重试当前请求
                config.headers['Authorization'] = 'Bearer ' + res.data.token
                return uni.request(config)
              } else {
                // 刷新token失败，清除token并跳转到登录页
                console.log('request.js: 业务状态码401，token刷新失败，准备跳转登录')
                removeToken()
                showConfirm('登录状态已过期，请重新登录', () => {
                  uni.reLaunch({
                    url: '/pages/login/login'
                  })
                })
                reject('401')
              }
            }).catch(error => {
              console.error('刷新token失败:', error)
              console.log('request.js: 业务状态码401，刷新token异常，准备跳转登录')
              removeToken()
              showConfirm('登录状态已过期，请重新登录', () => {
                uni.reLaunch({
                  url: '/pages/login/login'
                })
              })
              reject('401')
            }).finally(() => {
              isRefreshing = false
            })
          } else {
            // 将请求加入重试队列
            console.log('request.js: 业务状态码401，将请求加入重试队列')
            return new Promise(resolve => {
              retryRequests.push(token => {
                config.headers['Authorization'] = 'Bearer ' + token
                resolve(uni.request(config))
              })
            })
          }
        }
        
        // 如果响应中包含新的token，则更新token
        if (res.data.token) {
          console.log('request.js: 响应包含新token，更新token')
          setToken(res.data.token)
        }
        
        resolve(res.data)
      })
      .catch(error => {
        console.error('请求失败:', error)
        toast('请求失败，请重试')
        reject(error)
      })
  })
}

export default request
